package com.xyz.study.java.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Random;

/**
 * 代理
 */
public class ProxyTest {

    public static void main(String[] args) {
        Object[] elements = new Object[1000];
        for (int i = 0; i < elements.length; i++){
            Integer value = i + 1;
            InvocationHandler invocationHandler = new TraceHandler(value);
            Object proxy = Proxy.newProxyInstance(null, new Class[]{Comparable.class}, invocationHandler);
            elements[i] = proxy;
        }
        Integer key = new Random().nextInt(elements.length) + 1;
        int result = Arrays.binarySearch(elements, key);
        if (result >= 0){
            System.out.println("key is : " + key);
            System.out.println("search result is : " + elements[result]);
        }
    }

    static class TraceHandler implements InvocationHandler{

        private Object target;

        /**
         * Constructs a TranceHandler
         * @param target the implicit parameter of the method call 方法调用的隐式参数
         */
        TraceHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // print implicit argument 隐式参数
            System.out.print(target);


            // print the method name
            System.out.print("." + method.getName() + "(");

            // print explicit arguments 显式参数
            if (args != null) {
                for (int i = 0; i < args.length; i++){
                    System.out.print(args[i]);
                    if (i < args.length - 1){
                        System.out.print(", ");
                    }
                }
            }
            System.out.print(")");
            System.out.println("\n");

            // invoke actual method
            return method.invoke(target, args);
        }
    }
}
